package com.xc.ezplan.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xc.ezplan.admin.entity.AdminLocalStorage;
import com.xc.ezplan.admin.service.AdminLocalStorageService;
import com.xc.ezplan.admin.mapper.AdminLocalStorageMapper;
import com.xc.ezplan.admin.vo.AdminLocalStorageVo;
import com.xc.ezplan.cache.constants.RedisKey;
import com.xc.ezplan.cache.utils.CacheUtil;
import com.xc.ezplan.cache.utils.RedisUtils;
import com.xc.ezplan.core.base.BaseSearchBody;
import com.xc.ezplan.core.base.SearchCondition;
import com.xc.ezplan.core.exception.BadRequestException;
import com.xc.ezplan.core.properties.FileProperties;
import com.xc.ezplan.core.utils.FileUtil;
import com.xc.ezplan.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lixingchen
 * @date 2022/11/21
 * @description 本地存储实现类
 */
@Service
@RequiredArgsConstructor
@Primary
@CacheConfig(cacheNames = "localStorage")
public class AdminLocalStorageServiceImpl extends ServiceImpl<AdminLocalStorageMapper, AdminLocalStorage>
		implements AdminLocalStorageService {

	private final AdminLocalStorageMapper adminLocalStorageMapper;

	private final FileProperties properties;

	@Override
	public void download(AdminLocalStorageVo adminLocalStorageVo, HttpServletResponse response) throws IOException {
		List<AdminLocalStorage> adminLocalStorageList = adminLocalStorageMapper
				.selectList(new QueryWrapper<AdminLocalStorage>().lambda().eq(AdminLocalStorage::getName,
						adminLocalStorageVo.getName()));
		List<Map<String, Object>> list = new ArrayList<>();
		for (AdminLocalStorage adminLocalStorage : adminLocalStorageList) {
			Map<String, Object> map = new LinkedHashMap<>();
			map.put("文件名", adminLocalStorage.getRealName());
			map.put("备注名", adminLocalStorage.getName());
			map.put("文件类型", adminLocalStorage.getType());
			map.put("文件大小", adminLocalStorage.getSize());
			map.put("创建者", adminLocalStorage.getCreateBy());
			map.put("创建日期", adminLocalStorage.getCreateTime());
			list.add(map);
		}
		FileUtil.downloadExcel(list);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void create(String name, MultipartFile multipartFile) {
		FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize());
		String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
		String type = FileUtil.getFileType(suffix);
		File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type +  File.separator);
		if(ObjectUtil.isNull(file)){
			throw new BadRequestException("上传失败");
		}
		try {
			name = StringUtils.isBlank(name) ? FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) : name;
			AdminLocalStorage localStorage = new AdminLocalStorage(
					file.getName(),
					name,
					suffix,
					file.getPath(),
					type,
					FileUtil.getSize(multipartFile.getSize())
			);
			adminLocalStorageMapper.insert(localStorage);
		}catch (Exception e){
			FileUtil.del(file);
			throw e;
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteAll(List<Long> ids) {
		for (Long id : ids) {
			AdminLocalStorage adminLocalStorage = adminLocalStorageMapper.selectById(id);
			FileUtil.del(adminLocalStorage.getPath());
			adminLocalStorageMapper.deleteById(id);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateFile(AdminLocalStorageVo adminLocalStorageVo) {
		AdminLocalStorage adminLocalStorage = adminLocalStorageMapper.selectById(adminLocalStorageVo.getId());
		BeanUtils.copyProperties(adminLocalStorageVo, adminLocalStorage);
		adminLocalStorageMapper.update(adminLocalStorage, new UpdateWrapper<AdminLocalStorage>().lambda()
				.eq(AdminLocalStorage::getId, adminLocalStorageVo.getId()));
	}

	@Override
	public Object pageQueryFile(BaseSearchBody<AdminLocalStorage> baseSearchBody) {
		Page<AdminLocalStorage> page = baseSearchBody.getPage();
		SearchCondition searchCondition = baseSearchBody.getSearchCondition();
		List<Date> createTime = searchCondition.getCreateTime();
		LambdaQueryWrapper<AdminLocalStorage> queryWrapper = new QueryWrapper<AdminLocalStorage>().lambda().like(
				StringUtils.isNotBlank(searchCondition.getKeyWord()), AdminLocalStorage::getName,
				searchCondition.getKeyWord());
		if (!CollectionUtils.isEmpty(createTime) && createTime.size() == 2) {
			queryWrapper.between(AdminLocalStorage::getCreateTime, createTime.get(0), createTime.get(1));
		}
		return adminLocalStorageMapper.selectPage(page, queryWrapper);
	}

}
